#pragma once

#include "Angel.h"
#include <string.h>
#include <map>

#define theInv HSInventory::GetInstance()

#define HSES_NONE 0
#define HSES_WEAPON 1
#define HSES_HEAD 2
#define HSES_CHEST 3
#define HSES_LEGS 4
#define HSES_HANDS 5
#define HSES_FEET 6

class HSItem
{
public:
	unsigned int uiLevel;

	std::string sId;
	std::string sName;
	std::string sType;		// high level type: weapon, armor, other
	std::string sTex;
	std::string sDesc;
	std::string sAction;

	unsigned int uiValue;

	bool bStackable;
	unsigned int uiStackSize;

	virtual unsigned int GetEquipSlot()
	{
		return HSES_NONE;
	}

	virtual std::string GetStatsString() const;
};

class  HSWeapon : public HSItem
{
public:
	std::string sSubType;

	float fPhysAtk;
	float fPhysAtkBonus;
	float fAtkPower;
	float fAtkPowerBonus;

	bool bFireUnlocked;
	bool bWaterUnlocked;
	bool bAirUnlocked;
	bool bEarthUnlocked;

	float fFireAtk;
	float fWaterAtk;
	float fAirAtk;
	float fEarthAtk;

	float fFireAtkBonus;
	float fWaterAtkBonus;
	float fAirAtkBonus;
	float fEarthAtkBonus;

	unsigned int GetEquipSlot()
	{
		return HSES_WEAPON;
	}

	std::string GetStatsString() const;
};

class  HSArmor : public HSItem
{
public:
	std::string sSubType;

	float fDefense;
	float fFireDef;
	float fWaterDef;
	float fAirDef;
	float fEarthDef;

	float fDefenseBonus;
	float fFireDefBonus;
	float fWaterDefBonus;
	float fAirDefBonus;
	float fEarthDefBonus;

	unsigned int GetEquipSlot()
	{
		if ( sSubType == "head" ) return HSES_HEAD;
		if ( sSubType == "chest" ) return HSES_CHEST;
		if ( sSubType == "legs" ) return HSES_LEGS;
		if ( sSubType == "hands" ) return HSES_HANDS;
		if ( sSubType == "feet" ) return HSES_FEET;

		return HSES_NONE;
	}

	std::string GetStatsString() const;
};

class HSInventory : public MouseListener
{
protected:

	typedef std::map< std::string, HSItem* > HSItemMap;
	static HSItemMap smapItems;

	static HSInventory* sInv;
		
	static const int iCanvasLayer = 1000;
	static const int iBackgroundLayer = 1001;
	static const int iItemsLayer = 1002;
	static const int iTextLayer = 1003;

	bool bActive;

	void MouseMotionEvent(Vec2i screenCoordinates); 
	void MouseDownEvent(Vec2i screenCoordinates, MouseButtonInput button); 
	void MouseUpEvent(Vec2i screenCoordinates, MouseButtonInput button); 
	void MouseWheelEvent(const Vector2 &scrollOffset);

	static const int iCapacity = 48;
	static const int iWeapon = iCapacity + 100;
	static const int iHead = iCapacity + 101;
	static const int iChest = iCapacity + 102;
	static const int iLegs = iCapacity + 103;
	static const int iHands = iCapacity + 104;
	static const int iFeet = iCapacity + 105;

	HSItem* pItems[ iCapacity ];
	HSItem* pChest;
	HSItem* pLegs;
	HSItem* pHands;
	HSItem* pFeet;
	HSItem* pHead;
	HSItem* pWeapon;

	Actor aCanvas;

	Actor aChestBkg, aLegsBkg, aHandsBkg, aFeetBkg, aHeadBkg, aWeaponBkg;
	Actor aSlotsBkg[ iCapacity ];

	Actor aChest, aLegs, aHands, aFeet, aHead, aWeapon;
	Actor aSlots[ iCapacity ];

	TextActor taStats;
	TextActor taDesc;

	int iSelection;

	void UpdateTextures();
	void UpdateSelection();
	int GetSelectedObject( Vec2i screenCoordinates );
	int GetFreeSlot() const;
	void EquipItem( const int iIndex );
	void DisplayItemInfo( const HSItem* pItem );

public:

	HSInventory();

	bool HasItem( const std::string& sId );
	bool AddItem( const std::string& sId );

	void Activate();
	void Deactivate();

	static HSInventory& GetInstance();
	static bool LoadItems( const std::string& sItemDefs );
	static const HSItem* GetItem( const std::string& sId );
};
